home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / progjour / 1991 / 06 / alibtool / asmhdr.c next >
C/C++ Source or Header  |  1991-08-22  |  6KB  |  232 lines

  1. /*  asmhdr - process assembly language headers
  2.  
  3.     usage:  asmhdr document_file *.asm
  4.  
  5.     Borland    C>tcc -mc asmhdr.c wildargs.obj
  6.     Microsoft  C>cl  /AC asmhdr.c setargv.obj /link /noe
  7.  
  8.     Compile with compact memory model.
  9.  
  10.     John Otken, Soft Advances
  11. */
  12.  
  13. #include <ctype.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. #define LINE_SIZE       256
  19. #define MAX_ROUTINES    1000    /* maximum routines */
  20. #define READ_TEXT       "rt"
  21. #define WRITE_TEXT      "wt"
  22.  
  23.  
  24.  
  25. struct index_tag {
  26.     char *routine_name;
  27.     char *routine_header;
  28. } index[MAX_ROUTINES];
  29.  
  30.  
  31. struct public_tag {        /* link list of public procedure names */
  32.     struct public_tag *pub_next;
  33.     char   pub_name[1];
  34. } *public_names;
  35.  
  36.  
  37.  
  38. void process_asm_file(char *fn);
  39. void out_of_memory(void);
  40. int search_public_names(char *);
  41. int stricmp_pt(const struct index_tag *a, const struct index_tag *b);
  42.  
  43.  
  44.  
  45. char all_switch;        /* 0 to output only public procedures */
  46. unsigned index_cnt;        /* number of index entries */
  47. unsigned long coreused;        /* total storage used */
  48.  
  49.  
  50.  
  51. void main(int argc, char *argv[])
  52. {
  53.     int ai, i;
  54.     unsigned u;
  55.     FILE *fo;
  56.  
  57.     if (argc < 3) {
  58.         printf(
  59.         "asmhdr [-a] outfile *.asm\n"
  60.         "Extracts header comments from *.ASM files, sorts them, and\n"
  61.         "writes them to outfile.  Without -a, only extracts headers\n"
  62.         "for public procedures.  8-22-91");
  63.         exit(EXIT_SUCCESS);
  64.     }
  65.  
  66.     ai = 1;
  67.     if (strcmp(argv[ai], "-a") == 0)  {
  68.     all_switch = 1;
  69.     ai++;
  70.     }
  71.  
  72.     fo = fopen(argv[ai], READ_TEXT);
  73.     if (fo != NULL) {
  74.         printf("Error: %s exists!  Overwriting source file?\n", argv[ai]);
  75.         fclose(fo);
  76.         exit(EXIT_FAILURE);
  77.     }
  78.  
  79.     for (i = ai+1; i < argc; i++)
  80.         process_asm_file(argv[i]);
  81.  
  82.     qsort(index, index_cnt, sizeof(index[0]), stricmp_pt);
  83.  
  84.     fo = fopen(argv[ai], WRITE_TEXT);
  85.     if (fo == NULL) {
  86.         printf("Error opening output file: %s\n", argv[1]);
  87.         exit(EXIT_FAILURE);
  88.     }
  89.  
  90.     for (u = 0; u < index_cnt; u++)
  91.         fprintf(fo,"%s\n",index[u].routine_header);
  92.     fclose(fo);
  93.  
  94.     printf("Used %d of %d index entries.\n", index_cnt, MAX_ROUTINES);
  95.     printf("Used %lu bytes.\n", coreused);
  96. #ifdef __TURBOC__
  97.     printf("%lu free bytes.\n", (unsigned long) coreleft());
  98. #endif
  99. }
  100.  
  101.  
  102.  
  103.  
  104. void process_asm_file(char *fn)
  105. {
  106.     char *p, *q;
  107.     char line[LINE_SIZE];    /* file line buffer */
  108.     char pname[LINE_SIZE];    /* procedure name */
  109.     char *buf;            /* temp buffer */
  110.     unsigned s;
  111.     FILE *fi;
  112.     struct public_tag *x;
  113.  
  114.     if ((buf = malloc(3000)) == NULL)
  115.     out_of_memory();
  116.  
  117.     fi = fopen(fn, READ_TEXT);
  118.     if (fi == NULL) {
  119.         printf("Error opening input file: %s\n", fn);
  120.         exit(EXIT_FAILURE);
  121.     }
  122.  
  123.     while (fgets(line, LINE_SIZE, fi) != NULL)    /* skip title & include lines */
  124.     if (line[0] != '\t')  break;
  125.     while (fgets(line, LINE_SIZE, fi) != NULL)    /* skip blank lines */
  126.     if (line[0] != '\n')  break;
  127.  
  128.     /* extract public names from beginning of source file */
  129.     while (strncmp(line, "\tpublic\t", 8) == 0)  {
  130.  
  131.     for (q = p = line+8; isgraph(*q); q++)  ;    // find public name
  132.  
  133.     s = sizeof(struct public_tag)+(unsigned)(q-p)+1;// allocate new public
  134.     if ((x = calloc(s, 1)) == NULL)            //  structure
  135.         out_of_memory();
  136.  
  137.     x->pub_next = public_names;            // link public
  138.     public_names = x;
  139.  
  140.     s = (unsigned) (q-p);                // copy public name
  141.     q = x->pub_name;
  142.     for (; s>0; s--)  *q++ = *p++;
  143.     
  144.     if (fgets(line, LINE_SIZE, fi) == NULL)  break;
  145.     }
  146.  
  147.     while (fgets(line, LINE_SIZE, fi) != NULL) {
  148.         if (line[0] == ';'  &&  line[1] == ';'  &&  line[2] == '\t') {
  149.  
  150.             p = buf;
  151.             do {
  152.                 p = strcpy(p, line) + strlen(line);
  153.             } while (fgets(line, LINE_SIZE, fi) != NULL  &&  line[0] == ';');
  154.             if (*(p-1) == '\n'  &&  *(p-2) == ';')  p -= 2;
  155.             *p = '\0';
  156.  
  157.             p = buf+3;        /* extract routine name from header */
  158.             q = pname;
  159.             while (isprint(*p)) {
  160.                 if ((*q++ = *p++) == ' ')  *(q-1) = '_';
  161.             }
  162.             *q = '\0';
  163.  
  164.         if (search_public_names(pname))  {
  165.         if ((index[index_cnt].routine_header = strdup(buf)) == NULL)
  166.             out_of_memory();
  167.         if ((index[index_cnt++].routine_name = strdup(pname)) == NULL)
  168.             out_of_memory();
  169.         coreused += strlen(buf)+1 + strlen(pname)+1;
  170.         }
  171.         }
  172.     }
  173.  
  174.     while ((x = public_names) != NULL)  {
  175.     public_names = x->pub_next;
  176.     free(x);
  177.     }
  178.     free(buf);
  179.     fclose(fi);
  180. }
  181.  
  182.  
  183.  
  184.  
  185. void out_of_memory(void)
  186. {
  187.     printf("Out of memory");
  188.     exit(EXIT_FAILURE);
  189. }
  190.  
  191.  
  192.  
  193.  
  194. int search_public_names(char *target)
  195. {
  196.     int i,l;
  197.     char c, d, *p, *q;
  198.     struct public_tag *x;
  199.  
  200.     if (all_switch)  return 1;
  201.     if ((x = public_names) == NULL)  return 1;    /* return match if no publics */
  202.     
  203.     l = (int) strlen(target);
  204.  
  205.     while (x != NULL)  {
  206.     p = target;                /* compare names */
  207.     q = x->pub_name;
  208.  
  209.     for (i=l; i>0; i--) {
  210.         c = *p;
  211.         d = *q;
  212.         if ((c == ' ') && (d == '_'))  d = ' ';    /* space & underscore */
  213.         if ((c == '_') && (d == ' '))  c = ' ';    /* are equivalent */
  214.         if (c != d)  break;
  215.         p++;
  216.         q++;
  217.     }
  218.     if (i == 0)  return 1;            /* if match found */
  219.     
  220.     x = x->pub_next;
  221.     }
  222.     return 0;                    /* if no match found */
  223. }
  224.  
  225.  
  226.  
  227.  
  228. int stricmp_pt(const struct index_tag *a, const struct index_tag *b)
  229. {
  230.     return stricmp(a->routine_name, b->routine_name);
  231. }
  232.